'use strict'

import 'femtocrank/style.css'
import 'femtocrank/dark.css'
import './style.css'

import 'iconify-icon'

import { createClient } from '@connectrpc/connect'
import { createConnectTransport } from '@connectrpc/connect-web'

import { OliveTinApiService } from './resources/scripts/gen/olivetin/api/v1/olivetin_pb'

import { createApp, h } from 'vue'
import { createI18n } from 'vue-i18n'

import router from './resources/vue/router.js'
import App from './resources/vue/App.vue'

import { initWebsocket } from './js/websocket.js'
import combinedTranslations from '../lang/combined_output.json'

function getSelectedLanguage () {
  const storedLanguage = localStorage.getItem('olivetin-language')

  if (storedLanguage && storedLanguage !== 'auto') {
    return storedLanguage
  }

  if (storedLanguage === 'auto') {
    localStorage.removeItem('olivetin-language')
  }

  if (navigator.languages && navigator.languages.length > 0) {
    const available = Object.keys(combinedTranslations.messages || {})

    for (const candidate of navigator.languages) {
      const lowerCandidate = candidate.toLowerCase()
      const exact = available.find(locale => locale.toLowerCase() === lowerCandidate)

      if (exact) {
        return exact
      }

      const prefix = available.find(locale => locale.toLowerCase().startsWith(lowerCandidate.split('-')[0] + '-'))

      if (prefix) {
        return prefix
      }
    }
  }

  return 'en'
}

async function initClient () {
  const transport = createConnectTransport({
    baseUrl: window.location.protocol + '//' + window.location.host + '/api/'
  })

  window.client = createClient(OliveTinApiService, transport)
  window.initResponse = await window.client.init({})

  const i18nSettings = createI18n({
    legacy: false,
    locale: getSelectedLanguage(),
    fallbackLocale: 'en',
    messages: combinedTranslations.messages,
    postTranslation: (translated) => {
      const params = new URLSearchParams(window.location.search)

      if (params.has('debug-translations')) {
        return '____'
      } else {
        return translated
      }
    }
  })

  return i18nSettings
}

function setupVue (i18nSettings) {
  const app = createApp(App)

  app.use(router)
  app.use(i18nSettings)

  window.i18n = i18nSettings.global

  app.mount('#app')
}

function setupErrorDisplay (errorMessage) {
  const ErrorApp = {
    render() {
      return h('section', { class: 'bad', style: 'padding: 2em; text-align: center; margin: 2em auto;' }, [
        h('h2', 'OliveTin Init Failed'),
        h('p', errorMessage),
        h('p', 'Please check your browser console for more details.')
      ])
    }
  }

  const app = createApp(ErrorApp)
  app.mount('#app')
}

async function main () {
  try {
    const i18nSettings = await initClient()

    initWebsocket()

    setupVue(i18nSettings)
  } catch (err) {
    const errorMessage = err.message || 'Failed to initialize. Please check your configuration and try again.'
    console.error('Init failed:', err)
    setupErrorDisplay(errorMessage)
  }
}

main()
